home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 February: Tool Chest / Apple_Developer_Group_CD_Series_February_1998_Tool_Chest.iso / Sample Code / OffScreenControlUpdate / OffScreenControlUpdate.c < prev    next >
Encoding:
Text File  |  1997-06-19  |  6.8 KB  |  247 lines  |  [TEXT/CWIE]

  1.     //
  2.     //    You may incorporate this sample code into your
  3.     //    applications without restriction. This sample code has
  4.     //    been provided "AS IS" and the responsibility for its
  5.     //    operation is 100% yours. You are not permitted to
  6.     //    redistribute the source as "Apple sample code" after
  7.     //    having made changes. If you're going to re-distribute
  8.     //    the source, we require that you make it clear in the
  9.     //    source that the code was descended from Apple sample
  10.     //    code, but that you've made changes.
  11.     //
  12.  
  13. #define OLDROUTINELOCATIONS        0
  14. #define OLDROUTINENAMES            0
  15. #define SystemSevenOrLater        1
  16.  
  17. #ifndef __FONTS__
  18. #    include <Fonts.h>
  19. #endif
  20.  
  21. #ifndef __DIALOGS__
  22. #    include <Dialogs.h>
  23. #endif
  24.  
  25. #ifndef __QDOFFSCREEN__
  26. #    include <QDOffscreen.h>
  27. #endif
  28.  
  29. enum
  30. {
  31.     kDialogItemIndex_DrawButton = 3,
  32.     kDialogItemIndex_CheckBox
  33. };
  34.  
  35. static pascal OSErr InitMac (void)
  36. {
  37.     MaxApplZone ( );
  38.     InitGraf (&(qd.thePort));
  39.     InitFonts ( );
  40.     InitWindows ( );
  41.     InitMenus ( );
  42.     TEInit ( );
  43.     InitDialogs (nil);
  44.  
  45.     return noErr;
  46. }
  47.  
  48. static pascal GDHandle GetMaxControlDevice (ControlRef controlRef)
  49. {
  50.     GrafPtr        savePort            = qd.thePort;
  51.     Rect        globalControlRect    = (**controlRef).contrlRect;
  52.  
  53.     SetPort ((**controlRef).contrlOwner);
  54.     {
  55.         LocalToGlobal ((Point *) &(globalControlRect.top));
  56.         LocalToGlobal ((Point *) &(globalControlRect.bottom));
  57.     }
  58.     SetPort (savePort);
  59.  
  60.     return GetMaxDevice (&globalControlRect);
  61. }
  62.  
  63. static pascal OSErr BuggyDraw1ControlWithOffScreen (ControlRef controlRef, short transferMode)
  64. {
  65.     //
  66.     //    This doesn't work. Check boxes draw as push buttons. I suspect this
  67.     //    is because controls assume they live in a window, and for the
  68.     //    duration of the Draw1Control call in this function, the control
  69.     //    lives in a GWorld, not a window. Probably the CDEF dereferences
  70.     //    some offset beyond the end of the GWorld, since a window record
  71.     //    is bigger.
  72.     //
  73.  
  74.     OSErr err = noErr;
  75.  
  76.     GDHandle maxDevice = GetMaxControlDevice (controlRef);
  77.  
  78.     if (maxDevice)
  79.     {
  80.         GWorldPtr        grafWorld        = nil;
  81.         Rect            contrlRect        = (**controlRef).contrlRect;
  82.         PixMapHandle    contrlPixMapH    = (**maxDevice).gdPMap;
  83.         short            pixelDepth        = (**contrlPixMapH).pixelSize;
  84.         CTabHandle        cTable            = (**contrlPixMapH).pmTable;
  85.  
  86.         if (!(err = NewGWorld (&grafWorld,pixelDepth,&contrlRect,cTable,maxDevice,noNewDevice)))
  87.         {
  88.             GWorldPtr        saveGrafWorld    = nil;
  89.             GDHandle        saveGDH            = nil;
  90.             PixMapHandle    pixMapH            = GetGWorldPixMap (grafWorld);
  91.  
  92.             GetGWorld (&saveGrafWorld,&saveGDH);
  93.             SetGWorld (grafWorld,nil);
  94.  
  95.             if (LockPixels (pixMapH)) // this should always work, but be paranoid
  96.             {
  97.                 GrafPtr        contrlOwner        = (**controlRef).contrlOwner;
  98.                 BitMapPtr    srcBitMap        = &(((GrafPtr) grafWorld)->portBits),
  99.                             destBitMap        = &(contrlOwner->portBits);
  100.  
  101.                 EraseRect (&contrlRect);
  102.                 (**controlRef).contrlOwner = (GrafPtr) grafWorld;
  103.                 Draw1Control (controlRef);
  104.                 (**controlRef).contrlOwner = contrlOwner;
  105.  
  106.                 CopyBits (srcBitMap,destBitMap,&contrlRect,&contrlRect,transferMode,nil);
  107.  
  108.                 UnlockPixels (pixMapH);
  109.             }
  110.  
  111.             SetGWorld (saveGrafWorld,saveGDH);
  112.             DisposeGWorld (grafWorld);
  113.         }
  114.     }
  115.  
  116.     return err;
  117. }
  118.  
  119. static pascal Boolean GrafPortIsColor (GrafPtr gp)
  120. {
  121.     if (!gp) gp = qd.thePort;
  122.     return (0xC000 & (((CGrafPtr) gp)->portVersion)) ? true : false;
  123. }
  124.  
  125. static pascal OSErr Draw1ControlWithOffScreen (ControlRef controlRef)
  126. {
  127.     //
  128.     //    [1]        create a GWorld with the same coords as the control
  129.     //            and as deep as the deepest intersecting monitor
  130.     //    [2]        make sure nothing gets colorized by CopyBits
  131.     //    [3]        grab the screen pixels that will be under the control
  132.     //    [4]        make the control's GrafPort have the GWorld's pixels
  133.     //    [5]        draw the control into the off-screen bits
  134.     //    [6]        blast the control image onto the screen
  135.     //
  136.  
  137.     OSErr err = noErr;
  138.  
  139.     GrafPtr contrlOwner = (**controlRef).contrlOwner;
  140.  
  141.     if (!GrafPortIsColor (contrlOwner))
  142.         err = paramErr;
  143.         //    contrlOwner must be color because the GWorld must be color
  144.         //    and both ports must be the same
  145.     else
  146.     {
  147.         // begin 1
  148.  
  149.         GDHandle maxDevice = GetMaxControlDevice (controlRef);
  150.  
  151.         if (!maxDevice)
  152.             err = nilHandleErr;
  153.         else
  154.         {
  155.             Rect            contrlRect    = (**controlRef).contrlRect;
  156.             GWorldPtr        grafWorld    = nil;
  157.             PixMapHandle    gdPMap        = (**maxDevice).gdPMap;
  158.             short            pixelSize    = (**gdPMap).pixelSize;
  159.             CTabHandle        pmTable        = (**gdPMap).pmTable;
  160.  
  161.             if (!(err = NewGWorld (&grafWorld,pixelSize,&contrlRect,pmTable,maxDevice,0)))
  162.             {
  163.                 PixMapHandle grafWorldPixMapH = GetGWorldPixMap (grafWorld);
  164.  
  165.                 if (!grafWorldPixMapH)
  166.                     err = nilHandleErr;
  167.                 else if (!LockPixels (grafWorldPixMapH))
  168.                     err = updPixMemErr;
  169.                 else
  170.                 {
  171.                     // end 1
  172.  
  173.                     BitMapPtr    grafWorldBitMap        = &(((GrafPtr) grafWorld)->portBits),            // 3,4,6
  174.                                 controlBitMap        = &(contrlOwner->portBits);                        // 3,4,6
  175.                     BitMap        saveControlBitMap    = *controlBitMap;                                // 4
  176.                     RGBColor    rgbFgColor            = grafWorld->rgbFgColor,                        // 2
  177.                                 rgbBkColor            = grafWorld->rgbBkColor;                        // 2
  178.                     GWorldPtr    saveGrafWorld        = nil;                                            // 2
  179.                     GDHandle    saveGDH                = nil;                                            // 2
  180.  
  181.                     GetGWorld (&saveGrafWorld,&saveGDH);                                            // 2
  182.  
  183.                     SetGWorld (grafWorld,nil);                                                        // 2
  184.                     ForeColor (blackColor);                                                            // 2
  185.                     BackColor (whiteColor);                                                            // 2
  186.                     CopyBits (controlBitMap,grafWorldBitMap,&contrlRect,&contrlRect,srcCopy,nil);    // 3
  187.                     RGBForeColor (&rgbFgColor);                                                        // 2
  188.                     RGBBackColor (&rgbBkColor);                                                        // 2
  189.  
  190.                     *controlBitMap = *grafWorldBitMap;                                                // 4
  191.                     PortChanged (contrlOwner);                                                        // 4
  192.                     Draw1Control (controlRef);                                                        // 5
  193.                     *controlBitMap = saveControlBitMap;                                                // 4
  194.                     PortChanged (contrlOwner);                                                        // 4
  195.  
  196.                     SetGWorld ((CGrafPtr)contrlOwner,nil);                                            // 2
  197.                     rgbFgColor = ((CGrafPtr)contrlOwner)->rgbFgColor,                                // 2
  198.                     rgbBkColor = ((CGrafPtr)contrlOwner)->rgbBkColor;                                // 2
  199.                     ForeColor (blackColor);                                                            // 2
  200.                     BackColor (whiteColor);                                                            // 2
  201.                     CopyBits (grafWorldBitMap,controlBitMap,&contrlRect,&contrlRect,srcCopy,nil);    // 6
  202.                     RGBForeColor (&rgbFgColor);                                                        // 2
  203.                     RGBBackColor (&rgbBkColor);                                                        // 2
  204.  
  205.                     SetGWorld (saveGrafWorld,saveGDH);                                                // 2
  206.                     UnlockPixels (grafWorldPixMapH);                                                // 1
  207.                 }
  208.                 DisposeGWorld (grafWorld);                                                            // 1
  209.             }
  210.         }
  211.     }
  212.  
  213.     return err;
  214. }
  215.  
  216. void main (void)
  217. {
  218.     if (InitMac ( ))
  219.         SysBeep (10);
  220.     else
  221.     {
  222.         DialogRef dlgRef = GetNewDialog (129,nil,(WindowRef)-1);
  223.         if (dlgRef)
  224.         {
  225.             short itemHit;
  226.  
  227.             SetDialogDefaultItem (dlgRef,kStdOkItemIndex);
  228.  
  229.             do
  230.             {
  231.                 ModalDialog (nil,&itemHit);
  232.  
  233.                 if (itemHit == kDialogItemIndex_DrawButton)
  234.                 {
  235.                     short iType; Handle iHandle; Rect iRect;
  236.                     GetDialogItem (dlgRef,kDialogItemIndex_CheckBox,&iType,&iHandle,&iRect);
  237.                     if (Draw1ControlWithOffScreen ((ControlRef)iHandle))
  238.                         SysBeep (10);
  239.                 }
  240.             }
  241.             while (itemHit != kStdOkItemIndex);
  242.  
  243.             DisposeDialog (dlgRef);
  244.         }
  245.     }
  246. }
  247.